package feizhou.untils.tools;

import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.log4j.Logger;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


/**
 * 
 * @author dengpeng
 * 2013-3-27 下午05:38:38
 */
public class ObjectUtil {

	private static Logger log = Logger.getLogger(ObjectUtil.class);
	
	public static String objectToString(Object obj) {
		StringBuffer str = new StringBuffer(obj.getClass().getSimpleName() + ":[");
		List<Field> fields = getFieldList(obj.getClass());
		for (Field f : fields) {
			String fieldName = f.getName();
			String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			try {
				Method getter = obj.getClass().getMethod(getterName);
				Object value = getter.invoke(obj);
				str.append(fieldName).append("=").append(value).append(", ");
			} catch (Exception e) {
				continue;
			}
		}
		if (str.length() > 1) {
			str.delete(str.length() - 2, str.length());
			str.append("]");
		}
		return str.toString();
	}
	
	public static Object getFieldValue(Object obj, Field f) {
		try {
			Method getMethod = obj.getClass().getMethod(getGetterName(f.getName()), null);
			Object value = getMethod.invoke(obj, null);
			return value;
		} catch (Exception e) {
			//throw new RuntimeException(e);
			log.warn("can not find getter for field ["+f.getName()+"]... please check");
			return null;
		}
	}
	
	public static List<Part> object2StringPart(Object obj) {
		List<Part> list = new ArrayList<Part>();
		object2StringPart(list, obj);
		return list;
	}
	private static void object2StringPart(List<Part> list, Object obj) {
		List<Field> fields = getFieldList(obj.getClass());
		for (Field f : fields) {
			String fieldName = f.getName();
			String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			try {
				Method getter = obj.getClass().getMethod(getterName);
				Object value = getter.invoke(obj);
				if (value != null) {
					put2PartList(list, f.getType(), fieldName, value);
				}
			} catch (Exception e) {
				continue;
			}
		}
	}

	private static void put2PartList(List<Part> list, Class<?> clazz, String fieldName, Object value) {
		if (isBaseType(clazz)) {
			list.add(new StringPart(fieldName, value+"", "UTF-8"));
		} else if (Date.class == clazz) {
			list.add(new StringPart(fieldName, DateUtil.format(DateUtil.DATETIME, (Date) value)));
		} else if (Timestamp.class == clazz) {
			list.add(new StringPart(fieldName, DateUtil.format(DateUtil.DATETIME, new Date(((Timestamp) value).getTime()))));
		} else {
			object2StringPart(list, value);
		}
	}
	

	public static void setFieldValue(Object obj, Field f, Object value) {
		try {
			Method setMethod = obj.getClass().getMethod(getSetterName(f.getName()), f.getType());
			setMethod.invoke(obj, value);
		} catch (Exception e){
			//throw new RuntimeException(e);
			log.warn("can not find setter for field ["+f.getName()+"]... please check");
		}
	}
	
	public static String getSetterName(String field) {
		String setter = "set" + field.substring(0, 1).toUpperCase() + field.substring(1);
		return setter;
	}
	
	public static String getGetterName(String field) {
		String getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
		return getter;
	}
	/**
	 * 判断一个Class的类型是否是基础类型。
	 * @return
	 */
	private static boolean isBaseType(Class clazz)
	{
		if(Integer.class == clazz || Double.class == clazz || Float.class ==  clazz ||  Boolean.class == clazz || 
			String.class == clazz || Long.class == clazz || Short.class == clazz || Byte.class == clazz || Character.class == clazz
			||
			int.class == clazz || double.class == clazz || float.class ==  clazz ||  boolean.class == clazz || 
			long.class == clazz || short.class == clazz || byte.class == clazz || char.class == clazz)
			return true;
		else
			return false;
	}
	private static boolean isArray(Class clazz) {
		if(Integer[].class == clazz || Double[].class == clazz || Float[].class ==  clazz ||  Boolean[].class == clazz || 
				String[].class == clazz || Long[].class == clazz || Short[].class == clazz || Byte[].class == clazz || Character[].class == clazz
				||
				int[].class == clazz || double[].class == clazz || float[].class ==  clazz ||  boolean[].class == clazz || 
				long[].class == clazz || short[].class == clazz || byte[].class == clazz || char[].class == clazz)
				return true;
			else
				return false;
	}

	public static List<Field> getFieldList(Class<?> clazz) {
		if (!clazz.getSuperclass().equals(Object.class)) {
			List<Field> list = getFieldList(clazz.getSuperclass());
			list.addAll(Arrays.asList(clazz.getDeclaredFields()));
			return list;
		}
		else {
			List<Field> list = new ArrayList<Field>();
			list.addAll(Arrays.asList(clazz.getDeclaredFields()));
			return list;
		}
	}
}
